package com.shelpe.services.simbasync.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.shelpe.services.simbasync.dto.CatDataDto;
import com.shelpe.services.simbasync.exception.RequestParamException;
import com.shelpe.services.simbasync.model.Category;
import com.shelpe.services.simbasync.model.Products;
import com.shelpe.services.simbasync.model.Users;
import com.shelpe.services.simbasync.model.mongo.InsightCatData;
import com.shelpe.services.simbasync.service.CategoryService;
import com.shelpe.services.simbasync.service.ProductsService;
import com.shelpe.services.simbasync.service.UserService;
import com.shelpe.services.simbasync.util.Util;

@RestController
@RequestMapping(value="/simbasync")
public class CategoryController {

	private static final Logger logger = LoggerFactory.getLogger(CategoryController.class);
	
    @Autowired
    private UserService userService;
    
	@Autowired
	private ProductsService productService;
	
	@Autowired
	private CategoryService categoryService;
	
    @RequestMapping("/tenants/{user}/@category")
	@ResponseBody
    public CatDataDto syncProductCategory(@PathVariable("user") String user){
    	
    	boolean isNumber = user.matches("-?[0-9]+.*[0-9]*");
		
		return isNumber ? syncCategory(null, Long.valueOf(user)) : syncCategory(user, null);
    }
   
    @RequestMapping("/category")
	@ResponseBody
    public CatDataDto syncInsightCategoryData(@RequestParam("category_ids") String cids){
    	
    	CatDataDto dto = new CatDataDto();
    	dto.setProcess("syncInsightCategoryData");
    	
    	Date beginProcessTime = new Date();
    	
    	List<Users> users = userService.getAllUsers();
    	if(users != null && users.size() > 0){
    		Users user = users.iterator().next();
    		Map<String, String> map = Util.getTaskRange();
    		List<InsightCatData> res = categoryService.getInsightCategoryData(user.getUserId(), cids, map.get("startDate"), map.get("endDate"));
    		if(res != null && res.size() > 0){
        		categoryService.saveInsightCategoryData(res);
        		dto.setAddNum(res.size());
    		}
    	}
    	
    	Date endProcessTime = new Date();
    	long durTime = endProcessTime.getTime() - beginProcessTime.getTime();
		dto.setDurTime(durTime);
		
    	return dto;
    }
    
	private CatDataDto syncCategory(String nick, Long userId){
		
		if(userId == null){
			userId = userService.getUserIdByNick(nick);
		}
		
		if(nick == null){
			nick = userService.getNickByUserId(userId);
		}
		
		if(nick == null || userId == null){
			logger.warn("nick or userId is null, do nothing");
			throw new RequestParamException();
		}
		logger.info(">>>syncCategory nick {}, userId {}", nick, userId);
		CatDataDto dto = new CatDataDto();
		dto.setNick(nick);
		dto.setUserId(userId);
		dto.setProcess("syncCategory");
		Date beginProcessTime = new Date();
		
		List<Products> products = productService.getItemsByUserId(userId);
		
		Set<Integer> cids = new HashSet<Integer>();
		if(products != null && products.size() > 0){
			for(Products product : products){
				if(product.getCid() != 0){
					cids.add(product.getCid());
				}
			}
		}
		
		if(cids != null && cids.size() > 0){
			List<Integer> cidList = new ArrayList<Integer>(cids);
			List<Category> catList = categoryService.getCategoryListByIds(cidList);
			List<Integer> foundCids = new ArrayList<Integer>(); 
			if(catList != null && catList.size() > 0){
				for(Category cat : catList){
					foundCids.add(cat.getCatId());
				}
			}

			cidList.removeAll(foundCids);
			if(cidList != null && cidList.size() > 0){
				
				List<Category> result = categoryService.getCategoryFromProxy(userId, cidList);
				dto.setAddNum(categoryService.insertCategoryList(result));
			}
		}
		
		Date endProcessTime = new Date();
		long durTime = endProcessTime.getTime() - beginProcessTime.getTime();
		dto.setDurTime(durTime);
		
		return dto;
	}
	
	
}
